package com.slipper.ai.flow.support;

import com.slipper.ai.flow.INodeDealer;
import com.slipper.ai.flow.vo.*;
import com.slipper.util.Tool;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Component("aiConditionNodeDealer")
public class ConditionNodeDealer implements INodeDealer {
    @Override
    public String getType() {
        return NodeVO.TYPE_CONDITION;
    }

    @Override
    public List<LineVO> doDeal(FlowVO flow, NodeVO node, NodeInstVO nodeInst) {
        if (!(node instanceof ConditionNodeVO conditionNode)) throw new RuntimeException("节点类型不正确！");
        if (conditionNode.getConditionList().isEmpty()) throw new RuntimeException("条件分支不能为空！");

        int index = -1;
        String conditionId = null;
        String conditionName = null;
        for (int i=0; i<conditionNode.getConditionList().size(); i++) {
            ConditionVO condition = conditionNode.getConditionList().get(i);
            if (isNextLine(condition.getGroupList(), nodeInst.getInput())) {
                index = i;
                conditionId = condition.getId();
                conditionName = condition.getName();
                break;
            }
        }

        Map<String, Object> outputMap = new HashMap<>();
        outputMap.put("分支索引", index < 0 ? -1 : (index + 1));
        outputMap.put("分支名称", index < 0 ? "" : (conditionName == null ? "分支条件 " + (index + 1) : conditionName));
        nodeInst.setOutput(outputMap);

        if (Tool.isNotBlank(conditionId)) {
            String id = "source_handle_" + conditionId;
            return flow.getLines()
                    .stream()
                    .filter(line -> line.getSourceHandle().equals(id))
                    .collect(Collectors.toList());
        } else {
            String id = "source_handle_" + node.getId();
            return flow.getLines()
                    .stream()
                    .filter(line -> line.getSourceHandle().equals(id))
                    .collect(Collectors.toList());
        }
    }

    public boolean isNextLine(List<ConditionGroupVO> conditionList, Map<String, Object> dataMap) {
        conditionList.forEach(item -> item.setGroup(item.getGroup() == null ? 93517 : item.getGroup()));
        Map<Integer, List<ConditionGroupVO>> conditionMap = conditionList.stream()
                .collect(Collectors.groupingBy(ConditionGroupVO::getGroup));
        for (List<ConditionGroupVO> list : conditionMap.values()) {
            if (isPassCondition(list, dataMap)) return true;
        }
        return false;
    }

    private boolean isPassCondition(List<ConditionGroupVO> conditionList, Map<String, Object> dataMap) {
        for(ConditionGroupVO condition : conditionList) {
            Object data = dataMap.get(condition.getName());
            String condValue = condition.getValue() == null ? "" : condition.getValue();
            String fieldValue = data == null ? "" : data.toString();

            boolean isCondNumeric = condValue.matches("-?\\d+(\\.\\d+)?");
            boolean isFieldNumeric = fieldValue.matches("-?\\d+(\\.\\d+)?");

            int compareResult = isCondNumeric && isFieldNumeric
                    ?  new BigDecimal(fieldValue).compareTo(new BigDecimal(condValue))
                    : fieldValue.compareTo(condValue);

            boolean match = switch (condition.getType()) {
                case "包含" -> fieldValue.contains(condValue);
                case "不包含" -> !fieldValue.contains(condValue);
                case "小于" -> compareResult < 0;
                case "小于等于" -> compareResult <= 0;
                case "等于" -> compareResult == 0;
                case "大于" -> compareResult > 0;
                case "大于等于" -> compareResult >= 0;
                case "不等于" -> compareResult != 0;
                default -> false;
            };

            if (!match) {
                return false;
            }
        }

        return true;
    }
}
